/*
 TO DO LIST:
 * new board + 5 submarines in c'tor
 * out of board check
 * submarines are not one over the other
 * submarines are not /
 * toString
 */

 
package model;

import java.util.Random;
import submarinesControl.SubmarinesControl;


/**
 *
 * @author Karnit Genchay
 */
public class Board
{
    private Square[][] board;

    public Square[][] getBoard() {
        return board;
    }
    private static final int SIZE_OF_BOARD = 11;
    private Submarine [] submarines;
    private static final char BOMBED = 'X';
    private int activeSubmarines;

    public int getActiveSubmarines() {
        return activeSubmarines;
    }

//    c'tor - creates the empty board
     public Board(int subNum)
     {
         board= new Square[SIZE_OF_BOARD][SIZE_OF_BOARD];
         for(int i=0; i<SIZE_OF_BOARD; i++) //row
             for(int j=0; j<SIZE_OF_BOARD; j++)
                   board[i][j] =  new Square (i, j);
         submarines = new Submarine[subNum];
         activeSubmarines = submarines.length;
     } 

     public boolean attack(Square sq){
        sq.setVal(BOMBED);
        Submarine bombedSubmarine = getSubmarineBySquare(sq);
        
        if (bombedSubmarine != null) {
            Boolean didKill = bombedSubmarine.isDown();

            // Update submarine count if its down
            if (didKill)
            {
                activeSubmarines--;
            }
        }
        
         return (sq.isHaveSubmarine());     
     }
     // Returns submarine if apears in square or else null
     public Submarine getSubmarineBySquare(Square theSquare) {
         for (Submarine currSubmarine : this.submarines) {
             for (Square currSquare : currSubmarine.getSquares()) {
                 if (currSquare.getCol() == theSquare.getCol() &&
                         currSquare.getRow() == theSquare.getRow())
                 {
                     return (currSubmarine);
                 }
             }
         }
         
         return (null);
     }
     
   public void printSubmarinesDown(){
       int subsDown=subsDown();
       System.out.println("There are "+submarines.length + " submarines on the board.");
       System.out.println(subsDown +"  down, "+ (submarines.length-subsDown) + " left.");
   }
   public boolean allSubsDown(){
       return (subsDown()==submarines.length);
   }
   public int subsDown(){
       int subsDown=0;
        for (int i = 0; i < submarines.length; i++) 
            if( submarines[i].isDown())
                       subsDown++;
        return subsDown;
   }
     public boolean isAlreadyBombed(Square square ){
            return (square.getVal()==BOMBED);
     }
     public Square getSquareByPositionString(String strSquare){
         int arr[] = stringToIntArray_XXX(strSquare);
         return board[arr[1]][arr[0]];
     }
     public Square getSquare(int col, int row){ return board[row][col];}
     
     public int printSubmarinesAndReturnLength(){
         for (int i = 0; i < submarines.length; i++) 
             System.out.println(i+". " +submarines[i]);
         return submarines.length;
     }
     public void changeSubmarine(int i,String position,String direction){
        submarines[i].unSetSubmarine();
        submarines[i].set(position, direction);
        setNewSubmarine(i,submarines[i]);
     }
     
     public int [] stringToIntArray_XXX(String s){
         
         int [] arr = new int [s.length()];

         arr[0] = ((int)s.charAt(0)) - 97;
         
         if (s.length() == 3) {
             arr[1] =9;
         } else {
             arr[1] = ((int) s.charAt(1)) - 48-1;
         }

         return arr;
     }   
     
     public int [] stringToIntArray(String s){
         
         int [] arr = new int [s.length()];

         for (int i=0; i < s.length(); i++) {
            arr[i] = charToInt(s.charAt(i));  
         }

         // if the int from the string is 10 or more 
         for (int i =2; i < s.length(); i++) {
            arr[1]=arr[1]*10+arr[i]-1;
         }

         return arr;
     }        
     
     public void setNewSubmarine(int subNumber,Submarine submarine){
         int col,row;
         int []arr;     
         arr=stringToIntArray(submarine.getPosition());
         col = arr[0];
         row=arr[1];
 
         try{    
         for(int i=0;i<submarine.getSize();i++){
             if(board[row][col].isHaveSubmarine()){
//                  System.out.println("Already has a submarine!");
                   throw new IllegalStateException();
             }               
                   board[row][col].setSubmarine();
                   submarine.setSquare(i,board[row][col]);
                  if(submarine.getDirection().equals("HORIZONTAL"))                   
                        col++;
                  else  if(submarine.getDirection().equals("VERTICAL")) 
                      row++;   
                  else{
//                         System.out.println("Neither HORIZONTAL nor VERTICAL");
                         throw new IllegalStateException();
                  }
         }
     }catch(IllegalStateException e){
             throw new RuntimeException();         }
         
         submarines[subNumber]=submarine; 
    }

public void printWithSubmarines(){
             for(int i=0; i<SIZE_OF_BOARD; i++)
         {
             for(int j=0; j<SIZE_OF_BOARD; j++)
                          board[i][j].printWithSubmarines();
             
          System.out.println();
         }
}
public void printBoardWithMarks(boolean [][]marked){
       for(int i=0; i<SIZE_OF_BOARD; i++)
         {
             for(int j=0; j<SIZE_OF_BOARD; j++)
                          board[i][j].printWithMarks(marked[i][j]);
             
          System.out.println();
         }
}
     public void print(){
        
         for(int i=0; i<SIZE_OF_BOARD; i++)
         {
             for(int j=0; j<SIZE_OF_BOARD; j++)
                          board[i][j].print();
          System.out.println();
         }
     }

    public Square getVal(int row, int col) 
    { 
        return board[row][col]; 
    }
    public void setVal(int row, int col, char value) 
    { 
        try {
            board[row][col].setVal(value);
        } catch (ArrayIndexOutOfBoundsException e) {
        }
    }
       public static  int charToInt (char ch)
    {
              if(ch>='A' && ch<='Z')
                return (int)(ch-'A');
              else 
                    return (int)(ch-'0'-1);
   }
          public static  char intToChar(int i) {return (char) (i+'A');}
          public final int returnSizeOfBoard(){return SIZE_OF_BOARD;}

    public Square[][] getSquares() {
        return board;
    }

    public void setRandomSubs() {
        Random rand = new Random();
        int col=0;
        int row=0;
        int direction=0;
        boolean submarinePlacedInBoard=false;
        
        for (int i = 0; i < submarines.length; i++) {
            submarinePlacedInBoard=false;
            while(submarinePlacedInBoard==false){
                col =  rand.nextInt(SIZE_OF_BOARD-1);
                row = rand.nextInt(SIZE_OF_BOARD-1);  
                direction=rand.nextInt(1);
                                
                
                if(direction==0) {   // 0 = VERTICAL   ||
                    if(col+submarines[i].getSize()<=SIZE_OF_BOARD-1){
//                        SubmarinesControl.updateSubmarineData(submarines[i],i);
//                        setNewSubmarine(i,submarines[i]);
//                       for (int j=col;j<col+submarines[i].getSize(); j++)
//                           board[row][j].setSubmarine();
                       submarines[i].set(""+('A'+col)+row, "VERTICAL");
                       submarinePlacedInBoard=true;
                    }
                }
                else{      //direction ==1 , 1=HORIZONTAL    __
                    if(row+submarines[i].getSize()<=SIZE_OF_BOARD-1){
//                        setNewSubmarine(i,submarines[i]);
//                       for (int j=row;j<row+submarines[i].getSize(); j++)
//                           board[j][col].setSubmarine();
                       submarines[i].set(""+('A'+col)+row, "HORIZONTAL");
                       submarinePlacedInBoard=true;
                    }
                }
            }
            
        }
    }

    public Submarine[] getSubmarines() {
        return submarines;
    }
}
